# _*_ coding:utf-8 _*_
# @Time  : 2023.08.11
# @Author: zizlee

# 权限管理
from fastapi import APIRouter, Body, Query
from pydantic import BaseModel, validator, conint, constr
from db_utils import BaseDatabaseConnection
from db_common import DBUserAuth
from utils import datetime_utils
from response import APIResponse
from constant.user import UserType
from constant.variety import VarietyConstants, AliasVariety
from constant.section_scope import SectionScope


class SectionItem(BaseModel):
    sec_name: constr(min_length=1)
    variety_scope: str

    @validator('variety_scope')
    def validate_variety_scope(cls, value):
        if value not in VarietyConstants.SCOPES.keys():
            raise ValueError('variety_scope invalidate!')
        return value


class UserSectionItem(BaseModel):
    user_id: int
    sec_key: str
    c_access: conint(ge=0, le=1) = 0
    r_access: conint(ge=0, le=1) = 0
    u_access: conint(ge=0, le=1) = 0
    d_access: conint(ge=0, le=1) = 0
    expire_date: str

    @validator('expire_date')
    def validate_expire_date(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('expire_date invalidate! must be `yyyy-MM-dd`')
        return value


class UserSectionVarietyItem(BaseModel):
    user_id: int
    sec_key: str
    variety_en: str
    r_access: conint(ge=0, le=1) = 0
    expire_date: str

    @validator('expire_date')
    def validate_expire_date(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('expire_date invalidate! must be `yyyy-MM-dd`')
        return value


class Auth:

    def get_user_type(self, conn: BaseDatabaseConnection, user_id: int):
        # 查询用户类型
        conn.cursor.execute("SELECT id,user_type FROM ruizhi_user WHERE id=%s LIMIT 1;", [user_id])
        user = conn.cursor.fetchone()
        return user['user_type'] if user else 0

    def retrieve_section(self):
        ret = SectionScope.SECTIONS
        return APIResponse.success(data={'data': ret})

    def create_user_section(self, auth_item: UserSectionItem):
        with BaseDatabaseConnection() as conn:
            user_type = self.get_user_type(conn, user_id=auth_item.user_id)
            if user_type not in UserType.SECTION_AUTH_SETS:
                return APIResponse.validate_error(detail='该用户无需设置板块功能权限，默认全板块有或者无。')
            exist_sql = "SELECT id FROM ruizhi_user_section WHERE sec_key=%s AND user_id=%s LIMIT 1;"
            conn.cursor.execute(exist_sql, [auth_item.sec_key, auth_item.user_id])
            exist_obj = conn.cursor.fetchone()
            if exist_obj:
                conn.cursor.execute("UPDATE ruizhi_user_section SET c_access=%s,r_access=%s,u_access=%s,d_access=%s,expire_date=%s WHERE id=%s LIMIT 1;",
                                    [auth_item.c_access, auth_item.r_access, auth_item.u_access, auth_item.d_access, auth_item.expire_date, exist_obj['id']])
            else:
                conn.cursor.execute("""
                    INSERT INTO ruizhi_user_section(user_id,sec_key,c_access,r_access,u_access,d_access,expire_date) VALUES (%s,%s,%s,%s,%s,%s,%s);
                """, [auth_item.user_id, auth_item.sec_key, auth_item.c_access, auth_item.r_access, auth_item.u_access, auth_item.d_access, auth_item.expire_date])
        return APIResponse.success(msg='设置用户权限成功!')

    def retrieve_user_section(self, user_id: int):
        with BaseDatabaseConnection() as conn:
            auth = DBUserAuth(db_conn=conn)
            ret = auth.section_access(user_id=user_id)
        return APIResponse.success(data={'data': ret})

    def create_user_section_variety(self, auth_item: UserSectionVarietyItem):
        # 如果是设置定制数据库板块的品种，无需在此设置
        if auth_item.sec_key == SectionScope.FLEX_DATALIB_KEY:
            return APIResponse.validate_error(detail='请移步【定制数据库管理】设置该板块的权限!')
        # 如果是设置资讯报告的板块，内容需要品种转为后端标准
        variety_en = auth_item.variety_en
        if auth_item.sec_key == SectionScope.INFOR_REPORT_KEY:
            alias_variety = AliasVariety()
            variety_en = alias_variety.report_alias(auth_item.variety_en)
        with BaseDatabaseConnection() as conn:
            user_type = self.get_user_type(conn, user_id=auth_item.user_id)
            if user_type not in UserType.VARIETY_AUTH_SETS:
                return APIResponse.validate_error(detail='该用户无需设置板块内品种权限，默认全品种有或者无。')
            exist_sql = "SELECT id FROM ruizhi_user_section_variety WHERE sec_key=%s AND user_id=%s AND variety_en=%s LIMIT 1;"
            conn.cursor.execute(exist_sql, [auth_item.sec_key, auth_item.user_id, variety_en])
            exist_obj = conn.cursor.fetchone()
            if exist_obj:
                conn.cursor.execute("UPDATE ruizhi_user_section_variety SET r_access=%s,expire_date=%s WHERE id=%s LIMIT 1;",
                                    [auth_item.r_access, auth_item.expire_date, exist_obj['id']])
            else:
                conn.cursor.execute("""
                    INSERT INTO ruizhi_user_section_variety(user_id,sec_key,variety_en,r_access,expire_date) VALUES (%s,%s,%s,%s,%s);
                """, [auth_item.user_id, auth_item.sec_key, variety_en, auth_item.r_access, auth_item.expire_date])
        return APIResponse.success(msg='设置用户板块内品种权限成功!')

    def retrieve_user_section_variety(self, user_id: int, sec_key: str):
        with BaseDatabaseConnection() as conn:
            auth = DBUserAuth(db_conn=conn)
            ret = auth.section_variety_access(sec_key=sec_key, user_id=user_id)
        return APIResponse.success(data={'data': ret})


auth_api = APIRouter()


# @auth_api.post('/section/create/')  # 权限模块创建
# def create_auth_section(sec_item: SectionItem = Body(...)):
#     return Auth().create_auth_section(sec=sec_item)


@auth_api.get('/section/retrieve/')  # 权限模块查询
def retrieve_auth_section():
    return Auth().retrieve_section()


@auth_api.post('/userSection/create/')  # 用户模块权限
def user_section_auth(auth: UserSectionItem = Body(...)):
    return Auth().create_user_section(auth_item=auth)


@auth_api.get('/userSection/retrieve/')  # 用户模块权限
def user_section_auth(uid: int = Query(...)):
    return Auth().retrieve_user_section(user_id=uid)


@auth_api.post('/userSectionVariety/create/')  # 用户模块品种权限
def user_section_variety_auth(auth: UserSectionVarietyItem = Body(...)):
    return Auth().create_user_section_variety(auth_item=auth)


@auth_api.get('/userSectionVariety/retrieve/')  # 用户模块品种权限
def user_section_variety_auth(uid: int = Query(...), sec_key: str = Query(...)):
    return Auth().retrieve_user_section_variety(user_id=uid, sec_key=sec_key)
